package it.aqquadro.arex;

import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ArexDispatcher extends HttpServlet {
	@SuppressWarnings("unused")
	private static final Logger log = Logger.getLogger(ArexDispatcher.class.getName());
	
	@SuppressWarnings({ "rawtypes" })
	private Arex getAction(HttpServletRequest req, HttpServletResponse resp) throws IOException {
		
		String pathInfo = req.getPathInfo();
		
		if ( pathInfo != null ) {
			
			String action = getActionClassName(pathInfo);
			
			try {
				Class[] parametersArray = { HttpServletRequest.class, HttpServletResponse.class };
				
				Constructor ct = Class.forName( action ).getConstructor( parametersArray );

				return (Arex) ct.newInstance( req, resp );
				
			} catch (SecurityException e) {
				throw new ArexException("SecurityException");
				
			} catch (NoSuchMethodException e) {
				throw new ArexException("NoSuchMethodException");
				
			} catch (IllegalArgumentException e) {
				throw new ArexException("IllegalArgumentException");
				
			} catch (InstantiationException e) {
				throw new ArexException("InstantiationException");
				
			} catch (IllegalAccessException e) {
				throw new ArexException("IllegalAccessException");
				
			} catch (InvocationTargetException e) {
				throw new ArexException("InvocationTargetException");
				
			} catch (ClassNotFoundException e) {
				throw new ArexException("ClassNotFoundException");
				
			}
			
		} else {
			throw new ArexException("ClassNotFoundException");
		}
	}

	/**
	 * 
	 * @param pathInfo req.getPathInfo() - /MyClass
	 * @return
	 */
	private String getActionClassName(String pathInfo) {
		return pathInfo.substring(1).replace("/", ".");
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.get();
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.post();
	}
	
	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.put();
	}
	
	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.delete();
	}
	
	@Override
	protected void doHead(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.head();
	}
	
	@Override
	protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.options();
	}
	
	@Override
	protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Arex action = getAction(req, resp);
		action.trace();
	}
}